﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;

/// <summary>
/// 负责管理游戏界面及全局事件的核心组件
/// 功能包括：场景切换、菜单显示控制、游戏状态管理、鼠标交互逻辑、资源数值更新等
/// </summary>
public class UiManager : MonoBehaviour
{
    // --------------------------- 序列化字段（Inspector可配置） --------------------------- //
    /// <summary>退出游戏时加载的场景名称</summary>
    public string exitSceneName;

    /// <summary>UI画布组件：开始界面</summary>
    public GameObject startScreen;
    /// <summary>UI画布组件：暂停菜单</summary>
    public GameObject pauseMenu;
    /// <summary>UI画布组件：失败菜单</summary>
    public GameObject defeatMenu;
    /// <summary>UI画布组件：胜利菜单</summary>
    public GameObject victoryMenu;
    /// <summary>UI画布组件：关卡进行中的界面</summary>
    public GameObject levelUI;

    /// <summary>文本组件：显示金币数量</summary>
    public Text goldAmount;
    /// <summary>文本组件：显示失败次数</summary>
    public Text defeatAttempts;

    /// <summary>菜单显示延迟（用于动画过渡）</summary>
    public float menuDisplayDelay = 1f;

    // --------------------------- 私有状态变量 --------------------------- //
    /// <summary>游戏是否处于暂停状态</summary>
    private bool paused;
    /// <summary>是否正在拖拽相机</summary>
    private bool cameraIsDragged;
    /// <summary>鼠标拖拽起点坐标</summary>
    private Vector3 dragOrigin = Vector3.zero;
    /// <summary>相机控制组件引用</summary>
    private CameraControl cameraControl;

    // --------------------------- 倍速控制新增功能 --------------------------- //
    /// <summary>当前游戏速度（时间缩放系数）</summary>
    private float currentTimeScale = 1f;
    /// <summary>可选速度列表（1倍速、2倍速）</summary>
    private readonly float[] speedOptions = { 1f, 2f };
    /// <summary>当前速度索引（0=1x，1=2x）</summary>
    private int currentSpeedIndex = 0;

    // --------------------------- 生命周期方法 --------------------------- //
    void Awake()
    {
        // 获取场景中的相机控制组件
        cameraControl = FindObjectOfType<CameraControl>();

        // 断言检查：确保所有UI组件和依赖项已正确赋值
        Debug.Assert(
            cameraControl && startScreen && pauseMenu && defeatMenu &&
            victoryMenu && levelUI && defeatAttempts && goldAmount,
            "UiManager初始化参数错误：缺少必要组件引用"
        );
    }

    void OnEnable()
    {
        // 订阅全局事件
        EventManager.StartListening("UnitKilled", UnitKilled);    // 单位死亡事件（用于金币增加）
        EventManager.StartListening("ButtonPressed", ButtonPressed);  // 按钮点击事件（通用处理）
        EventManager.StartListening("SpeedButtonPressed", SpeedButtonHandler); // 倍速按钮事件（新增）
    }

    void OnDisable()
    {
        // 取消订阅事件
        EventManager.StopListening("UnitKilled", UnitKilled);
        EventManager.StopListening("ButtonPressed", ButtonPressed);
        EventManager.StopListening("SpeedButtonPressed", SpeedButtonHandler);
    }

    void Start()
    {
        // 游戏初始为暂停状态（显示开始界面）
        PauseGame(true);
    }

    void Update()
    {
        if (!paused) // 仅在非暂停状态处理输入
        {
            // --------------------------- 鼠标按下事件处理 --------------------------- //
            if (Input.GetMouseButtonDown(0)) // 左击
            {
                GameObject hittedObj = null; // 命中对象

                // --------------------------- 检测是否点击UI组件 --------------------------- //
                PointerEventData pointerData = new PointerEventData(EventSystem.current);
                pointerData.position = Input.mousePosition; // 设置鼠标位置
                List<RaycastResult> results = new List<RaycastResult>();
                EventSystem.current.RaycastAll(pointerData, results); // 射线检测所有UI元素

                if (results.Count > 0) // 命中UI组件
                {
                    // 遍历结果，寻找标签为"ActionIcon"的UI元素（如建造按钮）
                    foreach (RaycastResult res in results)
                    {
                        if (res.gameObject.CompareTag("ActionIcon"))
                        {
                            hittedObj = res.gameObject;
                            break;
                        }
                    }
                    // 触发"用户点击UI"事件，传递命中对象
                    EventManager.TriggerEvent("UserUiClick", hittedObj, null);
                }
                else // 未命中UI，检测游戏世界中的物体
                {
                    // 将屏幕坐标转换为世界坐标（2D场景使用ScreenToWorldPoint）
                    Vector2 screenPos = Input.mousePosition;
                    Vector2 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
                    // 2D射线检测，查找标签为塔、敌人或防御者的物体
                    RaycastHit2D[] hits = Physics2D.RaycastAll(worldPos, Vector2.zero); // 垂直检测

                    foreach (RaycastHit2D hit in hits)
                    {
                        if (hit.collider.CompareTag("Tower") ||
                            hit.collider.CompareTag("Enemy") ||
                            hit.collider.CompareTag("Defender"))
                        {
                            hittedObj = hit.collider.gameObject;
                            break;
                        }
                    }
                    // 触发"用户点击游戏物体"事件
                    EventManager.TriggerEvent("UserClick", hittedObj, null);
                }

                // --------------------------- 处理相机拖拽 --------------------------- //
                if (hittedObj == null) // 未点击任何物体，开始拖拽相机
                {
                    cameraIsDragged = true;
                    dragOrigin = Input.mousePosition; // 记录拖拽起点
                }
            }

            // 鼠标松开时停止拖拽
            if (Input.GetMouseButtonUp(0))
            {
                cameraIsDragged = false;
            }

            // 执行相机拖拽逻辑（根据鼠标移动距离计算相机偏移）
            if (cameraIsDragged)
            {
                // 将鼠标移动距离转换为视口坐标（范围0-1）
                Vector3 delta = Input.mousePosition - dragOrigin;
                Vector3 viewportDelta = Camera.main.ScreenToViewportPoint(delta);
                // 调用相机控制组件移动（反向是因为鼠标移动方向与相机移动方向相反）
                cameraControl.MoveX(-viewportDelta.x);
                cameraControl.MoveY(-viewportDelta.y);
            }
        }
    }

    // --------------------------- 场景加载相关方法 --------------------------- //
    private void LoadScene(string sceneName)
    {
        // 触发场景退出事件（用于资源清理等预处理）
        EventManager.TriggerEvent("SceneQuit", null, null);
        // 加载指定场景
        SceneManager.LoadScene(sceneName);
    }

    // --------------------------- 游戏状态控制方法 --------------------------- //
    private void ResumeGame()
    {
        // 切换到关卡界面并恢复游戏
        GoToLevel();
        PauseGame(false);
    }

    private void ExitFromLevel()
    {
        // 退出当前关卡，返回主菜单或指定场景
        LoadScene(exitSceneName);
    }

    private void CloseAllUI()
    {
        // 隐藏所有菜单界面
        startScreen.SetActive(false);
        pauseMenu.SetActive(false);
        defeatMenu.SetActive(false);
        victoryMenu.SetActive(false);
    }

    private void PauseGame(bool pause)
    {
        paused = pause;
        // 关键逻辑：暂停时时间缩放设为0，非暂停时应用当前倍速
        Time.timeScale = pause ? 0f : currentTimeScale;
        // 触发游戏暂停事件（传递暂停状态）
        EventManager.TriggerEvent("GamePaused", null, pause.ToString());
    }

    // --------------------------- 菜单界面切换方法 --------------------------- //
    private void GoToPauseMenu()
    {
        PauseGame(true); // 先暂停游戏
        CloseAllUI(); // 关闭其他界面
        pauseMenu.SetActive(true); // 显示暂停菜单
    }

    private void GoToLevel()
    {
        CloseAllUI(); // 关闭所有菜单
        levelUI.SetActive(true); // 显示关卡界面
        PauseGame(false); // 恢复游戏
    }

    public void GoToDefeatMenu()
    {
        // 启动协程：延迟显示失败菜单
        StartCoroutine("DefeatCoroutine");
    }

    private IEnumerator DefeatCoroutine()
    {
        yield return new WaitForSeconds(menuDisplayDelay); // 等待延迟时间
        PauseGame(true); // 暂停游戏
        CloseAllUI(); // 关闭其他界面
        defeatMenu.SetActive(true); // 显示失败菜单
    }

    public void GoToVictoryMenu()
    {
        StartCoroutine("VictoryCoroutine"); // 启动胜利菜单协程
    }

    private IEnumerator VictoryCoroutine()
    {
        yield return new WaitForSeconds(menuDisplayDelay); // 延迟显示

        PauseGame(true); // 暂停游戏
        CloseAllUI(); // 关闭其他界面

        // --------------------------- 胜利时保存游戏进度 --------------------------- //
        // 获取当前场景名称
        string currentLevel = SceneManager.GetActiveScene().name;
        // 更新最后完成的关卡
        DataManager.instance.progress.lastCompetedLevel = currentLevel;
        // 检查当前关卡是否已在已解锁列表中
        bool isLevelUnlocked = false;
        foreach (string level in DataManager.instance.progress.openedLevels)
        {
            if (level == currentLevel)
            {
                isLevelUnlocked = true;
                break;
            }
        }
        // 若未解锁，则添加到已解锁列表
        if (!isLevelUnlocked)
        {
            DataManager.instance.progress.openedLevels.Add(currentLevel);
        }
        // 保存游戏进度
        DataManager.instance.SaveGameProgress();

        victoryMenu.SetActive(true); // 显示胜利菜单
    }

    private void RestartLevel()
    {
        // 重新加载当前场景（实现关卡重置）
        LoadScene(SceneManager.GetActiveScene().name);
    }

    // --------------------------- 金币系统相关方法 --------------------------- //
    private int GetGold()
    {
        // 从文本组件解析金币数值（安全转换，失败返回0）
        int gold;
        return int.TryParse(goldAmount.text, out gold) ? gold : 0;
    }

    public void SetGold(int gold)
    {
        // 更新金币文本显示
        goldAmount.text = gold.ToString();
    }

    private void AddGold(int gold)
    {
        // 增加金币并更新显示
        SetGold(GetGold() + gold);
    }

    public bool SpendGold(int cost)
    {
        // 花费金币逻辑：检查余额是否足够
        int currentGold = GetGold();
        if (currentGold >= cost)
        {
            SetGold(currentGold - cost); // 扣除金币
            return true; // 成功
        }
        return false; // 失败
    }

    // --------------------------- 失败次数显示方法 --------------------------- //
    public void SetDefeatAttempts(int attempts)
    {
        defeatAttempts.text = attempts.ToString(); // 更新失败次数文本
    }

    // --------------------------- 事件回调方法 --------------------------- //
    private void UnitKilled(GameObject obj, string param)
    {
        if (obj.CompareTag("Enemy")) // 仅处理敌人死亡事件
        {
            // 获取敌人携带的金币数值组件
            Price price = obj.GetComponent<Price>();
            if (price != null)
            {
                AddGold(price.price); // 增加对应金币
            }
        }
    }

    private void ButtonPressed(GameObject obj, string param)
    {
        // 按钮点击事件统一处理
        switch (param)
        {
            case "Pause": GoToPauseMenu(); break; // 打开暂停菜单
            case "Resume": GoToLevel(); break;      // 恢复游戏
            case "Back": ExitFromLevel(); break;  // 返回主菜单
            case "Restart": RestartLevel(); break;   // 重启关卡
        }
    }

    // --------------------------- 倍速控制方法（新增功能） --------------------------- //
    private void SpeedButtonHandler(GameObject obj, string param)
    {
        if (param == "2x") // 仅处理2倍速按钮事件
        {
            ToggleSpeed(); // 切换游戏速度
        }
    }

    private void ToggleSpeed()
    {
        // 循环切换速度索引（0→1→0）
        currentSpeedIndex = (currentSpeedIndex + 1) % speedOptions.Length;
        currentTimeScale = speedOptions[currentSpeedIndex]; // 获取当前速度

        if (!paused) // 仅在非暂停状态应用速度
        {
            Time.timeScale = currentTimeScale; // 更新时间缩放
        }
    }

    // --------------------------- Buff提示方法（预留扩展） --------------------------- //
    public void ShowBuffNotice(string buffName)
    {
        // 待实现：显示临时Buff提示（如悬浮文字）
    }

    void OnDestroy()
    {
        StopAllCoroutines(); // 销毁时停止所有协程
    }
}